package core.util;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;

import com.thoughtworks.xstream.XStream;
import com.thoughtworks.xstream.converters.basic.DateConverter;
import com.thoughtworks.xstream.mapper.MapperWrapper;

public class XStreamUtil {
	
	@SuppressWarnings("unchecked")
	public static XStream newXStream() {
		XStream xstr = new XStream() {
			protected MapperWrapper wrapMapper(MapperWrapper next) {
				return new MapperWrapper(next) {
					public boolean shouldSerializeMember(Class definedIn, String fieldName) {
						return definedIn != Object.class ? super.shouldSerializeMember(definedIn, fieldName) : false;
					}
				};
			}
		};
		String fmt = "yyyy-MM-dd HH:mm:ss.S";
		String[] acpFmts = new String[] { fmt, "yyyy-MM-dd HH:mm:ss.S a", "yyyy-MM-dd HH:mm:ssz",
				"yyyy-MM-dd HH:mm:ss z", // JDK 1.3 needs both versions
				"yyyy-MM-dd HH:mm:ssa" };
		DateConverter dc = new DateConverter(fmt, acpFmts);
		xstr.registerConverter(dc);

		return xstr;
	}

	public static byte[] marshal(XStream xstream, Object obj) {
		try {
			ByteArrayOutputStream bos = new ByteArrayOutputStream();
			OutputStreamWriter osw = new OutputStreamWriter(bos, "utf-8");
			xstream.toXML(obj, osw);
			return bos.toByteArray();
		} catch (Exception e) {
			throw new RuntimeException(e.getMessage(), e);
		}
	}

	public static Object unmarshal(XStream xstream, byte[] data, int offset, int len) {
		try {
			ByteArrayInputStream bis = new ByteArrayInputStream(data, offset, len);
			InputStreamReader reader = new InputStreamReader(bis, "utf-8");
			return xstream.fromXML(reader);
		} catch (Exception e) {
			throw new RuntimeException(e.getMessage(), e);
		}
	}

	public static Object unmarshal(XStream xstream, byte[] data) {
		return unmarshal(xstream, data, 0, data.length);
	}
}
